package com.codeyang.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.codeyang.constant.AuthConstant;
import com.codeyang.domain.SysLoginUser;
import com.codeyang.domain.User;
import com.codeyang.mapper.SysLoginUserMapper;
import com.codeyang.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * 描述: 用户登录实现类
 *
 * @author CodeYang_Site
 * @version 2021/5/22 22:41
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private SysLoginUserMapper sysLoginUserMapper;

    @Autowired
    private UserMapper userMapper;


    @Value("${wx.appid}")
    private String appId;

    @Value("${wx.appsecret}")
    private String appSecret;

    @Value("${wx.tokenurl}")
    private String wxTokenUrl;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 用户的密码匹配校验交给了security了
     * 登录方法
     * 两个平台共用一套方法,根据请求头里的登录类型来做判断
     * header放一个loginType区别一下
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //1 拿到header判断是那个登录方式
//        HttpServletRequest request = (HttpServletRequest) RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = request.getRemoteAddr();
        String type = request.getHeader(AuthConstant.LOGIN_TYPE);
        if (StringUtils.isEmpty(type)) {
            return null;
        }
        switch (type) {
            case AuthConstant.SYS_USER:
                //后台的
                SysLoginUser sysLoginUser = sysLoginUserMapper.selectOne(new LambdaQueryWrapper<SysLoginUser>()
                        //TODO 这里的username如果不是id那么就无法定位一条记录
                        //
                        .eq(SysLoginUser::getUsername, username));
                if (!ObjectUtils.isEmpty(sysLoginUser)) {
                    //查询权限
                    // 查询权限
                    List<String> auths = sysLoginUserMapper.findAuthsById(sysLoginUser.getUserId());
                    if (!CollectionUtils.isEmpty(auths)) {
                        sysLoginUser.setAuths(auths);
                    }
                }
                return sysLoginUser;
            case AuthConstant.MEMBER:
                //走微信 那一套
                //1.组装URl
                // username是微信客户端自己生产的一个 code 标识用户的操作唯一

                String wxAuth = String.format(wxTokenUrl, appId, appSecret, username);
                //2.请求微信服务接口

                String wxTokenStrResult = null;
                try {
                    wxTokenStrResult = restTemplate.getForObject(wxAuth, String.class);
                } catch (RestClientException e) {
                    //这里可以抛出异常 在交给AOP,或者发给自己的异常 controller来管理写出
                    e.printStackTrace();
                }


                //3.拿到openid 用户的唯一id 是微信那边设置好了的 请求成功返回
                //微信返回的是一个json包
                JSONObject jsonObject = JSON.parseObject(wxTokenStrResult);
                String openId = jsonObject.getString("openid");
                //4.判断openid是否已经在系统里注册了,没有就注册,有就组装user对象返回
                if (StringUtils.hasText(openId)){
                    //success
                    User user = userMapper.selectById(openId);
                    if (ObjectUtils.isEmpty(user)){
                        //没有注册过,注册
                       user =  createUser(openId, ip);
                    }
                    return  user;
                }

            default:
                return null;

        }
    }

    /**
     * 注册用户到DB
     *
     * @param openId
     * @param ip
     * @return
     */
    private User createUser(String openId, String ip) {
        User user = User.builder()
                .userId(openId)
                .userRegtime(new Date())
                .modifyTime(new Date())
                .userLasttime(new Date())
                .userLastip(ip)
                .status(1)
                .userRegip(ip)
                .build();
        userMapper.insert(user);
        return user;
    }


//    public static void main(String[] args) {
//        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
//        String encode = bCryptPasswordEncoder.encode("123");
//        System.out.println(encode);
//    }
}
